interface Cache {
  set(key: string, value: string): void
  get(key: string): string | null
  setJSON<T>(key: string, jsonValue: T): void
  getJSON<T>(key: string): T | null
  remove(key: string): void
}

function createCache(storage: Storage): Cache {
  return {
    set(key: string, value: string) {
      if (key != null && value != null) {
        storage.setItem(key, value)
      }
    },
    get(key: string): string | null {
      if (key == null) {
        return null
      }
      return storage.getItem(key)
    },
    setJSON<T>(key: string, jsonValue: T) {
      if (jsonValue != null) {
        this.set(key, JSON.stringify(jsonValue))
      }
    },
    getJSON<T>(key: string): T | null {
      const value = this.get(key)
      if (value != null) {
        return JSON.parse(value)
      }
      return null
    },
    remove(key: string) {
      storage.removeItem(key)
    },
  }
}

const sessionCache: Cache = createCache(sessionStorage)
const localCache: Cache = createCache(localStorage)

interface Caches {
  session: Cache
  local: Cache
}

export default {
  /**
   * 会话级缓存
   */
  session: sessionCache,
  /**
   * 本地缓存
   */
  local: localCache,
} as Caches
